import {
	AppCodeListConfig,
	AppConfig,
	AppFuncConfig,
	AppViewConfig,
	AppCounterConfig,
	AppEntityConfig,
} from '@/config';
import { useAppStoreWithOut, useAuthResourceStoreWithOut } from '@/store';
import {
	AppController,
	AppLoadingHelper,
	IApp,
	IAppCodeListHelper,
	IAppConfig,
	IAppCounterHelper,
	IAppData,
	IAppFunc,
	IAppFuncHelper,
	IAppViewMsgHelper,
	IContext,
	IDialogHelper,
	IEntityDetail,
	IGlobalActionHelper,
	ILoadingHelper,
	INotificationHelper,
	IOpenViewHelper,
	IParam,
	IProjectSetting,
	IUIService,
	IViewLogicHelper,
} from '../core';
import { EntityServiceRegister, UIServiceRegister } from '@/register';
import {
	AppCodeListHelper,
	AppFuncHelper,
	DialogHelper,
	GlobalActionHelper,
	NotificationHelper,
	OpenViewHelper,
	ViewLogicHelper,
} from '@/helper';
import { i18n } from '@/locales';
import { router } from '@/router';
import { clearCookie } from 'qx-util';
import { AppViewMsgConfig } from '@/config/app-view-msg-config';
import { AppViewMsgHelper } from '@/helper/app-view-msg-helper';
import { Http } from '@/http';
import { ProjectSetting } from '@/setting';
import { AppCounterHelper } from '@/helper/counter-helper';
/**
 * 应用
 *
 * @export
 * @class App
 * @extends {AppController}
 */
export class App extends AppController {
	/**
	 * 应用对象
	 *
	 * @private
	 * @static
	 * @type {IApp}
	 * @memberof App
	 */
	private static app: IApp;

	/**
	 * 界面应用对象
	 *
	 * @private
	 * @type {IParam}
	 * @memberof App
	 */
	private UIAppInstance: IParam | undefined;

	/**
	 * 获取实例对象
	 *
	 * @public
	 * @static
	 * @return {*}  {IApp}
	 * @memberof App
	 */
	public static getInstance(): IApp {
		if (!this.app) {
			this.app = new App();
		}
		return this.app;
	}

	/**
	 * 设置界面应用对象
	 * @param UIApp
	 */
	setUIAppInstance(UIApp: IParam): void {
		this.UIAppInstance = UIApp;
	}

	/**
	 * 获取界面应用对象
	 */
	getUIAppInstance(): IParam | undefined {
		return this.UIAppInstance;
	}

	/**
	 * 获取数据服务
	 *
	 * @param {string} name
	 * @param {(IContext)} [context]
	 * @return {*}  {Promise<any>}
	 * @memberof App
	 */
	getDataService(name: string, context?: IContext): Promise<any> {
		return EntityServiceRegister.getInstance().getService(name, context);
	}

	/**
	 * 获取界面服务
	 *
	 * @param {string} name
	 * @param {IContext} [context]
	 * @return {*}  {Promise<IUIService>}
	 * @memberof App
	 */
	getUIService(name: string, context?: IContext): Promise<IUIService> {
		return UIServiceRegister.getInstance().getService(name, context);
	}

	/**
	 * 获取视图配置参数
	 *
	 * @return {*}  {IParam}
	 * @memberof App
	 */
	getAppViewConfig(): IParam {
		return AppViewConfig;
	}

	/**
	 * 获取应用功能配置参数
	 *
	 * @return {*}  {IAppFunc[]}
	 * @memberof App
	 */
	getAppFuncConfig(): IAppFunc[] {
		return AppFuncConfig;
	}

	/**
	 * 获取代码表配置参数
	 *
	 * @return {*}  {IParam}
	 * @memberof App
	 */
	getAppCodeListConfig(): IParam {
		return AppCodeListConfig;
	}

	/**
	 * 获取计数器配置参数
	 *
	 * @return {*}  {IParam}
	 * @memberof App
	 */
	getAppCounterConfig(): IParam {
		return AppCounterConfig;
	}

	/**
	 * 获取代码表辅助类
	 * @returns
	 */
	getAppCodeListHelper(): IAppCodeListHelper {
		return AppCodeListHelper.getInstance();
	}

	/**
	 * 获取计数器辅助类
	 * @returns
	 */
	getAppCounterHelper(): IAppCounterHelper {
		return AppCounterHelper.getInstance();
	}

	/**
	 * @description 获取应用是否启用权限
	 * @return {*}  {boolean}
	 * @memberof App
	 */
	getEnableAppPermission(): boolean {
		const { getEnablePermissionValid } = useAuthResourceStoreWithOut();
		const enableAppPermission = this.getProjectSetting().enableAppPermission;
		return getEnablePermissionValid && enableAppPermission;
	}

	/**
	 * 获取应用功能辅助类
	 *
	 * @return {*}  {IAppFuncHelper}
	 * @memberof App
	 */
	getAppFuncHelper(): IAppFuncHelper {
		return AppFuncHelper.getInstance();
	}

	/**
	 * @description 获取指定菜单是否存在权限
	 * @param {string} tag
	 * @return {*}  {boolean}
	 * @memberof App
	 */
	getAppMenuAuth(tag: string): boolean {
		const { getMenuData, getResourceData } = useAuthResourceStoreWithOut();
		if (Object.is(this.getProjectSetting().menuPermissionMode, 'RT')) {
			return getMenuData.some((authTag: string) => Object.is(authTag, tag));
		} else {
			return getResourceData.some((resourceTag: string) =>
				Object.is(resourceTag, tag)
			);
		}
	}

	/**
	 * @description 获取指定统一资源是否存在权限
	 * @param {string} tag
	 * @return {*}  {boolean}
	 * @memberof App
	 */
	getAppUniresAuth(tag: string): boolean {
		const { getResourceData } = useAuthResourceStoreWithOut();
		return getResourceData.some((codeName: string) => Object.is(codeName, tag));
	}

	/**
	 * @description 获取应用数据
	 * @return {*}  {IAppData}
	 * @memberof App
	 */
	getAppData(): IAppData {
		const { getAppData } = useAppStoreWithOut();
		return getAppData;
	}

	/**
	 * 获取打开视图辅助类
	 *
	 * @return {*}  {IOpenViewHelper}
	 * @memberof App
	 */
	getOpenViewHelper(): IOpenViewHelper {
		return OpenViewHelper.getInstance();
	}

	/**
	 * @description 获取消息提示辅助类
	 * @return {*}  {INotificationHelper}
	 * @memberof App
	 */
	getNotificationHelper(): INotificationHelper {
		return NotificationHelper.getInstance();
	}

	/**
	 * 获取应用加载辅助类
	 *
	 * @return {*}  {ILoadingHelper}
	 * @memberof App
	 */
	getAppLoadingHelper(): ILoadingHelper {
		return AppLoadingHelper.getInstance();
	}

	/**
	 * 获取全局行为辅助类
	 *
	 * @return {*}  {IGlobalActionHelper}
	 * @memberof App
	 */
	getGlobalActionHelper(): IGlobalActionHelper {
		return GlobalActionHelper.getInstance();
	}

	/**
	 * 获取视图逻辑辅助类
	 *
	 * @return {*}  {IViewLogicHelper}
	 * @memberof App
	 */
	getViewLogicHelper(): IViewLogicHelper {
		return ViewLogicHelper.getInstance();
	}

	/**
	 * 翻译
	 * @param str 源字符
	 * @param resTag  语言标识
	 * @memberof App
	 */
	ts(resTag: string, str: string = ''): string {
		if (resTag) {
			return i18n.global.t(resTag, str);
		} else {
			return str;
		}
	}

	/**
	 * @description 清除应用数据
	 * @return {*}  {boolean}
	 * @memberof App
	 */
	clearAppData(): boolean {
		try {
			clearCookie('ibzuaa-token', true);
			clearCookie('ibzuaa-expired', true);
			clearCookie('ibzuaa-user', true);
			// 清除应用级数据
			localStorage.removeItem('localdata');
			const { clearAppData } = useAppStoreWithOut();
			const { clearAuthData } = useAuthResourceStoreWithOut();
			clearAppData();
			clearAuthData();
			// 清除租户相关信息
			sessionStorage.removeItem('activeOrgData');
			sessionStorage.removeItem('dcsystem');
			sessionStorage.removeItem('orgsData');
			return true;
		} catch (error) {
			return false;
		}
	}

	/**
	 * 获取视图消息配置参数
	 *
	 * @return {*}  {IParam}
	 * @memberof App
	 */
	getAppViewMsgConfig(): IParam {
		return AppViewMsgConfig;
	}

	/**
	 * 获取视图消息辅助类
	 * @returns
	 */
	getAppViewMsgHelper(): IAppViewMsgHelper {
		return AppViewMsgHelper.getInstance();
	}

	/**
	 * 对话框提示辅助类
	 */
	getDialogHelper(): IDialogHelper {
		return DialogHelper.getInstance();
	}

	/**
	 * @description 跳转用户登录页
	 * @memberof App
	 */
	login(): void {
		this.clearAppData();
		router.push({ name: 'login' });
	}

	/**
	 * 关闭应用页面
	 * @memberof App
	 */
	closeView() {
		const { deletePage, historyPathList } = useAppStoreWithOut();
		const { currentRoute, push } = router;
		// 删除当前页面
		deletePage(currentRoute.value.fullPath);
		// 跳转前一个页面
		const length = historyPathList.length;
		if (length > 0) {
			const path = historyPathList[length - 1];
			if (Object.is(path, currentRoute.value.fullPath)) {
				return;
			} else {
				push({ path });
			}
		} else {
			const path: string | null = window.sessionStorage.getItem(
				this.getAppConfig().appName
			);
			if (path) {
				push({ path: path });
			} else {
				push('/');
			}
		}
	}

	/**
	 * 用户登出
	 */
	logout(): Promise<IParam> {
		return new Promise((resolve, reject) => {
			this.getDialogHelper().confirm(
				this.ts('function.generic.prompt', '提示'),
				this.ts(
					'function.generic.promptInformation',
					'是否退出系统, 是否继续?'
				),
				() => {
					const get: Promise<any> = Http.getInstance().get('/v7/logout');
					get
						.then((response: any) => {
							if (response.success) {
								this.login();
								resolve(response.data);
							}
						})
						.catch((error: any) => {
							reject(error);
						});
				}
			);
		});
	}

	/**
	 * 获取项目设置
	 *
	 * @return {*}  {IProjectSetting}
	 * @memberof App
	 */
	getProjectSetting(): IProjectSetting {
		return ProjectSetting;
	}

	/**
	 * 应用配置
	 *
	 * @return {*}  {IAppConfig}
	 * @memberof App
	 */
	getAppConfig(): IAppConfig {
		return AppConfig;
	}

	/**
	 * 获取应用实体配置信息
	 *
	 * @return {*}  {IEntityDetail[]}
	 * @memberof App
	 */
	getAppEntityConfig(): IEntityDetail[] {
		return AppEntityConfig;
	}
}
